package edu.stanford.prpl.impl;

import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.MessageFormat;
import java.util.HashSet;
import java.util.Set;

import edu.stanford.prpl.api.Device;
import edu.stanford.prpl.common.PRPLProperties;
import edu.stanford.prpl.common.util.IPAddress;
import edu.stanford.prpl.common.util.URIUtils;

public class DeviceImpl extends PRPLObjectImpl implements Device {

	public static final String PCM_DEVICE = "PCM";
	public static final String BLOB_SERVER_DEVICE = "BLOB";
	public static final String CACHE_DEVICE = "CACHE";

	String deviceName;
	String deviceURI;
	URL serverURL;
	Set<String> deviceRoles;

	public DeviceImpl(String deviceUri, URL hostURL, String... deviceRoles) {
		super(deviceUri);
		this.deviceURI = deviceUri;
		this.serverURL = hostURL;
		this.deviceRoles = new HashSet<String>();
		for (String role : deviceRoles) {
			if (role.equalsIgnoreCase(PCM_DEVICE) || role.equalsIgnoreCase(BLOB_SERVER_DEVICE)
					|| role.equalsIgnoreCase(CACHE_DEVICE)) {
				this.deviceRoles.add(role);
			}
		}
		this.deviceName = URIUtils.getDeviceName(deviceURI);
	}

	public DeviceImpl(String deviceName, String ownerKey, URL hostURL, String... deviceRoles) {
		this(URIUtils.getDeviceURI(ownerKey, deviceName), hostURL, deviceRoles);
	}

	//@Override
	public String getName() {
		return deviceName;
	}

	//@Override
	public URL getServerURL() {
		return serverURL;
	}

	//@Override
	public String getURI() {
		return deviceURI;
	}

	//@Override
	public boolean isBlobServer() {
		return this.deviceRoles.contains(BLOB_SERVER_DEVICE.toUpperCase());
	}

	//@Override
	public boolean isCache() {
		return this.deviceRoles.contains(CACHE_DEVICE.toUpperCase());
	}

	//@Override
	public boolean isPCM() {
		return this.deviceRoles.contains(PCM_DEVICE.toUpperCase());
	}

	private static Device currDevice;

	public static Device getCurrentDevice() {

		InetAddress ipAddr = IPAddress.getInterfaceIP();

		// If not init or host ip has changed, get a new current device
		boolean condition = (currDevice == null);
		condition |= (currDevice != null && currDevice.getServerURL() != null && !currDevice.getServerURL()
				.getHost().equals(ipAddr.getHostAddress()));

		if (condition) {
			String userKey = PRPLProperties.getProperty("prpl.user.key");
			String deviceName = PRPLProperties.getProperty("prpl.device.name");
			String deviceRoles = PRPLProperties.getProperty("prpl.device.server.type");

			// InetAddress ipAddr = IPAddress.getInterfaceIP();
			String apiURLFormat = PRPLProperties.getProperty("prpl.device.server.api.url");
			String apiPort = PRPLProperties.getProperty("prpl.device.server.api.port");
			String apiName = PRPLProperties.getProperty("prpl.device.server.api.name");
			if ( ipAddr == null)
			{
			    throw new RuntimeException ("Bad ip address");
			}
			
			
			String url = MessageFormat.format(apiURLFormat, ipAddr.getHostAddress(), apiPort, apiName);
			    
			
			try {
				currDevice = new DeviceImpl(deviceName, userKey, new URL(url), deviceRoles.split(" "));
			} catch (MalformedURLException e) {
				e.printStackTrace();
				currDevice = new DeviceImpl(deviceName, userKey, null, deviceRoles.split(" "));
			}
		}

		return currDevice;
	}
}
